#pragma once
extern "C"
{
#include "libavformat/avformat.h"
#include "libavcodec/avcodec.h"
#include "libswscale/swscale.h"
}
#include <string>
#include <vector>

class VideoSizeChange
{
private:
	struct StreamContext;
	struct ScaleContext;

private:
	int open_input_file();
	int open_output_file();
	void demux_decode_encode_mux(AVPacket* pkt);
	void decode_scale_encode_mux(AVPacket* pkt, bool flush = false);
	int scale_frame(int stream_index, AVFrame* frame, bool flush = false);
	void encode_mux(int stream_index, bool flush = false);
	void flush_all();

public:
	VideoSizeChange(const std::string& in, const std::string& out, int width, int height);
	~VideoSizeChange();

private:
	std::string in_filename;
	std::string out_filename;
	int width;
	int height;
	
	std::vector<StreamContext> stream_ctxs;
	std::vector<ScaleContext> sws_ctxs;
	AVFormatContext* ifmt_ctx = nullptr;
	AVFormatContext* ofmt_ctx = nullptr;
	AVPacket* packet = nullptr;
	AVFrame* frame = nullptr;
	AVPacket* enc_pkt = nullptr;
};

struct VideoSizeChange::StreamContext
{
	AVCodecContext* dec_ctx = nullptr;
	AVCodecContext* enc_ctx = nullptr;
	AVFrame* dec_frame = nullptr;
	int64_t pts = 1;
	~StreamContext();
};

struct VideoSizeChange::ScaleContext
{
	SwsContext* sws_ctx = nullptr;
	AVFrame* scaled_frame = nullptr;
	~ScaleContext();
};

